#include <boost/algorithm/string/join.hpp>
#include "riskmeasuretablemodel.h"
#include <QTableWidget>

using namespace boost;
using namespace std;
using namespace quic;

void RiskMeasureTableModel::setRiskMeasure(shared_ptr<RiskMeasure> riskMeasure)
{
    this->riskMeasure = riskMeasure;
    reset();

    numRows = 0;
    map<string,bool> nameMap;
    riskMeasureIndex.clear();

    indexRiskMeasure(riskMeasure, nameMap);
}

shared_ptr<RiskMeasure> RiskMeasureTableModel::getRiskMeasure(unsigned int index)
{
    return riskMeasureIndex[index];
}

void RiskMeasureTableModel::indexRiskMeasure(shared_ptr<RiskMeasure> riskMeasure,
                     map<string,bool> &nameMap)
{    
    if(nameMap.find(riskMeasure->getName()) == nameMap.end())
    {
        nameMap[riskMeasure->getName()] = true;
        if(numRows >= riskMeasureIndex.size())
            riskMeasureIndex.resize((riskMeasureIndex.size()+1)*2);
        riskMeasureIndex[numRows] = riskMeasure;
        numRows++;
    }

    for(RiskMeasure::Children::iterator it = riskMeasure->children.begin();
        it != riskMeasure->children.end(); ++it)
    {
        indexRiskMeasure(*it,nameMap);
    }
}

QVariant RiskMeasureTableModel::data(const QModelIndex &index, int role) const
{

    if (role != Qt::DisplayRole)
        return QVariant();

    shared_ptr<RiskMeasure> rm = riskMeasureIndex[index.row()];
    switch(index.column())
    {
    case 0:
        return rm->isStored();
    case 1:
        return algorithm::join(rm->parameters, ",").c_str();
    case 2:
        return rm->getModule().c_str();
    }

    return QVariant();
}

QVariant RiskMeasureTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    static const char *headerLabels[] = {"Store in h5", "Paremeters", "Module"};

    if (role != Qt::DisplayRole)
        return QVariant();

    if (orientation == Qt::Horizontal) {
       return headerLabels[section];
    }
    else if (orientation == Qt::Vertical) {
        shared_ptr<RiskMeasure> rm = riskMeasureIndex[section];
        string result = rm->getName();
        if(rm->isStored()) result = "[ " + result + " ]";
        return result.c_str();
    }

    return QVariant();
}

/*
Qt::ItemFlags RiskMeasureTableModel::flags(const QModelIndex &index) const
{
    if (!index.isValid())
        return Qt::ItemIsEnabled;

    return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
}
*/

bool RiskMeasureTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (index.isValid() && role == Qt::EditRole) {
        //int row = index.row();

        QString s;

        if (index.column() == 0)
            s = value.toString();
        else if (index.column() == 1)
            s = value.toString();
        else
            return false;

        //listOfPairs.replace(row, p);
        emit(dataChanged(index, index));

        return true;
    }

    return false;
}
